﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.IO;
using System.Web.UI;
using System.ComponentModel;

[assembly: System.Web.UI.WebResource("Studio.Web.WebControls.EagerTreeView.EagerTreeView.js", "text/javascript")]

namespace Studio.Web.WebControls
{
    /// <summary>
    /// The .NET TreeView's CheckBox are lazy.
    /// They won't post back automaticly.
    /// there's work around to __doPostBack by adding scripts
    /// But it can not support Ajax.NET
    /// That's why the control are created.
    /// By marstone.net, 2010/07/02 
    /// @SJTU
    /// </summary>
    [ClientScriptResource("Studio.Web.WebControls.EagerTreeView", "Studio.Web.WebControls.EagerTreeView.EagerTreeView.js")]
    public class EagerTreeView : TreeView, IScriptControl
    {
        
        protected override void Render(HtmlTextWriter writer)
        {
            if (this.AutoPostBack)
            {
                StringBuilder builder = new StringBuilder();

                using (StringWriter stringWriter = new StringWriter(builder))
                {
                    HtmlTextWriter tempWriter = new HtmlTextWriter(stringWriter);
                    base.Render(tempWriter);
                }
                string find = "<input type=\"checkbox\" ";
                // string replace = "<input type=\"checkbox\" onclick=\"" + 
                //    this.ReloadFunction + "(event);\" ";
                string replace = "<input type=\"checkbox\" onclick=\"__doPostBack('','');\" ";
                writer.Write(builder.ToString().Replace(find, replace));
            }
            else
            {
                base.Render(writer);
            }
        }

        [DefaultValue("ReloadTreeView")]
        public string ReloadFunction
        {
            get { return (string)(ViewState["ReloadFunction"] ?? "ReloadTreeView"); }
            set { ViewState["ReloadFunction"] = value; }
        }

        [Category("Behavior")]
        [Description("AutoPostBack when CheckBox clicked.")]
        [DefaultValue(typeof(bool), "True")]
        public bool AutoPostBack
        {
            get { return (bool)(ViewState["AutoPostBack"] ?? true); }
            set { ViewState["AutoPostBack"] = value; }
        }

        /// <summary>
        /// Gets the ScriptDescriptors that make up this control
        /// </summary>
        /// <returns></returns>
        IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
        {
            ScriptControlDescriptor descriptor = 
                new ScriptControlDescriptor("Studio.Web.WebControls.EagerTreeView", 
                    this.ClientID);
            
            // descriptor.AddProperty("normalImageUrl", this.ResolveClientUrl(this.ImageUrl));
            return new ScriptDescriptor[] { descriptor };
        }

        /// <summary>
        /// For debugging - setting this causes the extender to load the specified script instead of the one out of the resources.  This
        /// lets you set breakpoints and modify the script without rebuilding, etc.
        /// </summary>
        /// <remarks>
        /// Note to inheritors: If you do not wish the user to set the script path, override script path and throw a NotSupportedException on set.  Also decorate the ScriptPath attribute with a [Browsable(false)] and [EditorBrowsableState(EditorBrowsableState.Never)]
        /// </remarks>
        [DefaultValue("")]
        public virtual string ScriptPath
        {
            get { return (string)(ViewState["ScriptPath"] ?? string.Empty); }
            set { ViewState["ScriptPath"] = value; }
        }

        /// <summary>
        /// Gets the script references for this control
        /// </summary>
        /// <returns></returns>
        IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
        {
            if (!Visible) return null;

            List<ScriptReference> refs = new List<ScriptReference>();
            refs.AddRange(ScriptObjectBuilder.GetScriptReferences(GetType()));
            if (ScriptPath.Length > 0)
            {
                refs.Add(new ScriptReference(ScriptPath));
            }
            return refs;
        }
    }
}
